Java 源码学习之java.util.Vector
Vector
是Java
编程中最常用的容器类之一,它是基于动态的数组实现的,在面试时常常被与ArrayList
作比较!
看过源码的小伙伴可能有相同的感觉:进入Vector.Java
会顿一会儿,还以为自己点错进去ArrayList
的源码文件了呢!是的,Vector
与ArrayList
的实现基本相似,同样是基于动态数组,同样是需要扩容,本文在接下来的源码分析中与ArraryList
重复的部分不再累赘,如需要了解的同学请点入进ArrarList源码分析
Vertor的1倍扩容
还记得
ArrayList
每次扩容为元数组的0.5倍不?Vector
在进行扩容操作时与ArrayList
略微不同
1 | /** |
细心的小伙伴可以发现Vector
中多了一个capacityIncrement
变量,该变量是用于指定每次扩容的增量,如果不指定该变量,在grow
中可以发现Vector
默认就扩容为原数组的1倍
线程安全
Vertor
是线程安全的
Vertor
源码中另一个比较显眼的地方就是绝大部分方法都有synchronized
关键字,大家都知道这个关键字是用于线程同步的,所以Vector
类是线程安全的!
但是即使它所有的方法都被修饰成同步,也不意味着调用它的时候永远都不需要同步手段了:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38private static Vector<Integer> vector=new Vector<Integer>();
public static void main(String[] args) {
while(true)
{
for(int i=0;i<10;i++)
{
vector.add(i);
}
Thread removeThread=new Thread(new Runnable(){
@Override
public void run()
{
for(int i=0;i<vector.size();i++)
{
vector.remove(i);
}
}
});
Thread printThread=new Thread(new Runnable(){
@Override
public void run()
{
for(int i=0;i<vector.size();i++)
{
System.out.println(vector.get(i));
}
}
});
removeThread.start();
printThread.start();
while(Thread.activeCount()>20);
}
}
大家运行此段代码时 跑了一小段时间之后会发现有ArrayIndexOutOfBoundsException异常,这里Vector
的get,remove,size方法尽管有synchronized
修饰,但是在多线程环境中,如果不在方法端额外做同步措施的话,这段代码仍然是不安全的,如果一个线程删除了序号i的元素之后,另一个线程去访问这个i的话就直接回抛异常,所以保证这段代码安全还需要再run
里面再添加synchronized
修饰
总结
Vector
的实现与ArrayList
基本一致Vector
在扩容时可以指定每次扩容的增长,如果不指定则默认增加1倍Vector
是线程安全的,但是在多线程环境下可能还是需要用synchronized
关键词才能保证真正的安全
参考
- 《深入理解Java虚拟机》.周志明,第十三章,Page388-389
本作品采用[知识共享署名-非商业性使用-相同方式共享 2.5]中国大陆许可协议进行许可,我的博客欢迎复制共享,但在同时,希望保留我的署名权kubiCode,并且,不得用于商业用途。如您有任何疑问或者授权方面的协商,请给我留言。